package com.yonyou.pmclouds.measureindex.service.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.measureindex.entity.IndexExcelQueryVO;
import com.yonyou.pmclouds.measureindex.entity.IndexExcelShowVO;
import com.yonyou.pmclouds.measureindex.entity.MeasureIndexRefVO;
import com.yonyou.pmclouds.measureindex.entity.MeasureIndexVO;
import com.yonyou.pmclouds.measureindex.mapper.MeasureIndexMapper;
import com.yonyou.pmclouds.measureindex.service.rmiitf.MeasureIndexQuery;
import com.yonyou.pmclouds.organization.entity.OrganizationShowVO;
import com.yonyou.pmclouds.organization.entity.OrganizationVO;
import com.yonyou.pmclouds.organization.rmiitf.OrganizationQuery;
import com.yonyou.pmclouds.plan.entity.ScheduleItemShowVO;
import com.yonyou.pmclouds.plan.entity.ScheduleItemVO;
import com.yonyou.pmclouds.plan.entity.ScheduleShowVO;
import com.yonyou.pmclouds.plan.entity.ScheduleVO;
import com.yonyou.pmclouds.plan.planindex.entity.PlanIndexVO;
import com.yonyou.pmclouds.plan.planindex.rmiitf.IPlanIndexQuery;
import com.yonyou.pmclouds.plan.rmiitf.IScheduleItemQueryService;
import com.yonyou.pmclouds.plan.rmiitf.IScheduleQueryService;
import com.yonyou.pmclouds.project.entity.ProjectShowVO;
import com.yonyou.pmclouds.project.entity.ProjectVO;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import com.yonyou.pmclouds.projecttype.entity.ProjectTypeShowVO;
import com.yonyou.pmclouds.projecttype.entity.ProjectTypeVO;
import com.yonyou.pmclouds.projecttype.rmiitf.ProjectTypeQuery;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

/**
 * @author th
 * @date 2019/11/14 11:16
 */
@Service(interfaceClass = MeasureIndexQuery.class, version = ApplicationConsts.APPLICATION_VERSION)
public class MeasureIndexQueryImpl implements MeasureIndexQuery {
    @Autowired
    private MeasureIndexMapper measureIndexMapper;
    @Autowired
    private IScheduleQueryService scheduleQueryService;
    @Autowired
    private IScheduleItemQueryService itemQueryService;
    @Autowired
    private IPlanIndexQuery planIndexQuery;
    @Autowired
    private MeasureIndexQuery measureIndexQuery;
    @Autowired
    private ProjectSimpleQuery projectSimpleQuery;
    @Autowired
    private OrganizationQuery organizationQuery;
    @Autowired
    private ProjectTypeQuery projectTypeQuery;

    @Override
    public List<MeasureIndexRefVO> indexRefQuery(String pkTenant, String keyword) {
        return measureIndexMapper.indexRefQuery(pkTenant, keyword);
    }

    @Override
    public Map<String, MeasureIndexVO> queryByPks(String[] pks) {
        if (ArrayUtils.isEmpty(pks))
            return new HashMap<>(0);

        LinkedHashMap<String,MeasureIndexVO> result= new LinkedHashMap<String, MeasureIndexVO>();
        List<MeasureIndexVO> vos = measureIndexMapper.queryByPks(pks);
        if (CollectionUtils.isEmpty(vos))
            return new HashMap<>(0);

        for (MeasureIndexVO vo : vos) {
            result.put(vo.getPkMeasureindex(), vo);
        }

        return result;
    }

    @Override
    public List<MeasureIndexVO> queryByProjectIds(String[] pkProjects) {
        List<PlanIndexVO> planIndexVOS = planIndexQuery.queryByProjectIds(pkProjects);
        if (planIndexVOS==null||planIndexVOS.size()==0) {
            return new ArrayList<>();
        }
        List<String> pks=new ArrayList<>();
        for (PlanIndexVO planIndexVO:planIndexVOS){
            pks.add(planIndexVO.getPkMeasureIndex());
        }
        List<MeasureIndexVO> indexVOS = measureIndexMapper.queryByPks(pks.toArray(new String[0]));
        return indexVOS;
    }

    @Override
    public List<IndexExcelShowVO> queryIndexBySingleProject(IndexExcelQueryVO queryVO) throws BusinessException {
        if (queryVO != null) {
            //map<根计划主键，VO>
            Map<String, ScheduleVO> scheduleVOMap = new HashMap<>();
            //过滤根计划
            ScheduleVO[] scheduleVOS = scheduleQueryService.queryByIdsAndProjectId(queryVO.getPkProject(), queryVO.getPkSchedule(), queryVO.getStartDate(), queryVO.getEndDate());
            if (ArrayUtils.isEmpty(scheduleVOS)){
                return null;
            }
            //根计划主键
            List<String> pks = new ArrayList<>();
            for (ScheduleVO scheduleVO : scheduleVOS) {
                pks.add(scheduleVO.getPkSchedule());
                scheduleVOMap.put(scheduleVO.getPkSchedule(), scheduleVO);
            }
            //根计划对应的末级子计划
            //map<末级子计划主键,VO>
            Map<String, ScheduleItemVO> itemMap = new HashMap<>();
            List<ScheduleItemVO> scheduleItemVOS = itemQueryService.queryByPkSchedulesOnlyEnd(pks.toArray(new String[0]));
            if (scheduleItemVOS==null||scheduleItemVOS.size()==0){
                return null;
            }
            //末级子计划主键
            pks.clear();
            for (ScheduleItemVO scheduleItemVO : scheduleItemVOS) {
                pks.add(scheduleItemVO.getPkScheduleItem());
                itemMap.put(scheduleItemVO.getPkScheduleItem(), scheduleItemVO);
            }
            //末级计划对应的计划指标
            List<PlanIndexVO> planIndexVOS = planIndexQuery.queryIndexBySingleProject(queryVO.getPkMeasureindex(), pks.toArray(new String[0]), queryVO.getStartDate(), queryVO.getEndDate());
            if (planIndexVOS==null||planIndexVOS.size()==0){
                return null;
            }
            //按指标分组<指标主键，map<根计划主键,计划指标>>
            Map<String, Map<String, List<PlanIndexVO>>> planIndexVOMap = new HashMap<>();
            for (PlanIndexVO planIndexVO : planIndexVOS) {
                Map<String, List<PlanIndexVO>> indexMap = planIndexVOMap.get(planIndexVO.getPkMeasureIndex());
                if (indexMap == null) {
                    indexMap = new HashMap<String, List<PlanIndexVO>>();
                }
                List<PlanIndexVO> planList = indexMap.get(itemMap.get(planIndexVO.getPkPlan()).getPkSchedule());
                if (planList == null) {
                    planList = new ArrayList<PlanIndexVO>();
                }
                planList.add(planIndexVO);
                indexMap.put(itemMap.get(planIndexVO.getPkPlan()).getPkSchedule(), planList);
                planIndexVOMap.put(planIndexVO.getPkMeasureIndex(), indexMap);
            }

            //指标主键集合
            pks.clear();
            for (PlanIndexVO indexVO : planIndexVOS) {
                pks.add(indexVO.getPkMeasureIndex());
            }
            // 查询指标档案
            List<IndexExcelShowVO> indexVOList = new ArrayList<>();
            Map<String, MeasureIndexVO> measureIndexVOMap = measureIndexQuery.queryByPks(pks.toArray(new String[0]));
            //封装返回对象
            for (Map.Entry<String, MeasureIndexVO> indexEntry : measureIndexVOMap.entrySet()) {
                List<ScheduleShowVO> scheduleVOList = new ArrayList<>();
                //指标档案
                MeasureIndexVO indexVO = indexEntry.getValue();
                IndexExcelShowVO indexExcelShowVO = new IndexExcelShowVO();
                indexExcelShowVO.setCode(indexVO.getCode());
                indexExcelShowVO.setName(indexVO.getName());
                indexExcelShowVO.setUnit(indexVO.getUnit());
                for (Map.Entry<String, List<PlanIndexVO>> planEntry : planIndexVOMap.get(indexEntry.getKey()).entrySet()) {
                    String key = planEntry.getKey();
                    ScheduleVO scheduleVO = scheduleVOMap.get(key);
                    ScheduleShowVO scheduleShowVO = new ScheduleShowVO();
                    scheduleShowVO.setName(scheduleVO.getName());
                    List<PlanIndexVO> value = planEntry.getValue();
                    //指标总数量
                    Double sumNum = new Double(0);
                    List<ScheduleItemShowVO> itemShowVOS=new ArrayList<>();
                    for (PlanIndexVO planIndexVO : value) {
                        if (planIndexVO.getCompletionsNum()==null){
                            planIndexVO.setCompletionsNum(Double.valueOf(0));
                        }
                        sumNum += planIndexVO.getCompletionsNum();
                        ScheduleItemVO scheduleItemVO = itemMap.get(planIndexVO.getPkPlan());
                        ScheduleItemShowVO scheduleItemShowVO = new ScheduleItemShowVO();
                        scheduleItemShowVO.setName(scheduleItemVO.getName());
                        scheduleItemShowVO.setExpectTotal(planIndexVO.getCompletionsNum());
                        itemShowVOS.add(scheduleItemShowVO);
                    }
                    scheduleShowVO.setSumNum(sumNum);
                    scheduleShowVO.setScheduleItemShowVOS(itemShowVOS);
                    scheduleVOList.add(scheduleShowVO);
                }
                indexExcelShowVO.setScheduleShowVOS(scheduleVOList);
                indexVOList.add(indexExcelShowVO);
            }
            return indexVOList;
        }
        return new ArrayList<IndexExcelShowVO>();
    }

    @Override
    public OrganizationShowVO queryIndexofMultiOrg(IndexExcelQueryVO queryVO) throws BusinessException {
        if (queryVO != null) {
            String tenantId = RuntimeEnvironment.getTenantId();
            //tenantId = "x61tnmfx";
            List<ProjectVO> projectVOS =new ArrayList<>();
            if (queryVO.getPkOrg().equals(tenantId)){
                projectVOS= projectSimpleQuery.queryProjectsByTypeAndOrgs(tenantId, null, queryVO.getPkProjectType(), queryVO.getPkProject());
            }else {
                projectVOS=  projectSimpleQuery.queryProjectsByTypeAndOrgs(tenantId, queryVO.getPkOrg(), queryVO.getPkProjectType(), queryVO.getPkProject());
            }
            //过滤项目集合项目集合
            if (projectVOS==null||projectVOS.size()==0) {
                return null;
            }
            List<String> pks = new ArrayList<>();
            //map<项目主键，组织主键>
            Map<String, String> projectOrgMap = new HashMap<>();
            //map<项目主键，项目>
            Map<String, ProjectVO> projectVOMap = new HashMap<>();
            Set<String> typeIds=new HashSet<>();
            for (ProjectVO projectVO : projectVOS) {
                pks.add(projectVO.getPkProject());
                projectOrgMap.put(projectVO.getPkProject(), projectVO.getPkOrg());
                projectVOMap.put(projectVO.getPkProject(), projectVO);
            }
            //过滤根计划
            ScheduleVO[] scheduleVOS = scheduleQueryService.queryByIdsAndProjectId(pks.toArray(new String[0]), queryVO.getPkSchedule(), queryVO.getStartDate(), queryVO.getEndDate());
            if(ArrayUtils.isEmpty(scheduleVOS)){
                return new OrganizationShowVO();
            }
            if (ArrayUtils.isEmpty(scheduleVOS)){
                return null;
            }
            //根计划对应的子计划
            pks.clear();
            for (ScheduleVO scheduleVO : scheduleVOS) {
                pks.add(scheduleVO.getPkSchedule());
            }
            List<ScheduleItemVO> scheduleItemVOS = itemQueryService.queryByPkSchedulesOnlyEnd(pks.toArray(new String[0]));
            if (scheduleItemVOS==null||scheduleItemVOS.size()==0){
                return null;
            }
            //子计划对应的计划指标
            pks.clear();
            for (ScheduleItemVO scheduleItemVO : scheduleItemVOS) {
                pks.add(scheduleItemVO.getPkScheduleItem());
            }
            List<PlanIndexVO> planIndexVOS = planIndexQuery.queryIndexBySingleProject(queryVO.getPkMeasureindex(), pks.toArray(new String[0]), queryVO.getStartDate(), queryVO.getEndDate());
            if (planIndexVOS==null||planIndexVOS.size()==0){
                return null;
            }
            for (PlanIndexVO planIndexVO:planIndexVOS){
                    typeIds.add(projectVOMap.get(planIndexVO.getPkProject()).getPkProjectType());
            }
            //指标档案
            pks.clear();
            for (PlanIndexVO indexVO : planIndexVOS) {
                pks.add(indexVO.getPkMeasureIndex());
            }
            // 查询指标档案
            Map<String, MeasureIndexVO> measureIndexVOMap = measureIndexQuery.queryByPks(pks.toArray(new String[0]));
            //查询组织
            OrganizationVO organizationVO=new OrganizationVO();
            if (!tenantId.equals(queryVO.getPkOrg())){
                organizationVO= organizationQuery.queryByPkSrc(tenantId,queryVO.getPkOrg());
            }
            if (organizationVO==null){
                return new OrganizationShowVO();
            }
            //封装展示数据
            OrganizationShowVO organizationShowVO = new OrganizationShowVO();
                //项目类型
                ProjectTypeVO[] projectTypeVOS = projectTypeQuery.queryByIds(typeIds.toArray(new String[0]));
                Map<String,ProjectTypeVO> projectTypeMap=new HashMap<>();
                for (ProjectTypeVO projectTypeVO:projectTypeVOS){
                    projectTypeMap.put(projectTypeVO.getPkProjectType(),projectTypeVO);
                }
                //组织分组 map<组织主键，map<项目类型主键,map<指标主键，map<项目主键，计划指标集合>>>>
                Map<String,Map<String, Map<String, Map<String, List<PlanIndexVO>>>>> orgMap=new LinkedHashMap<>();
                for (PlanIndexVO planIndexVO : planIndexVOS) {
                    Map<String, Map<String, Map<String, List<PlanIndexVO>>>> typeMap = orgMap.get(projectOrgMap.get(planIndexVO.getPkProject()));
                    if (typeMap==null){
                        typeMap=new LinkedHashMap<>();
                    }
                    Map<String, Map<String, List<PlanIndexVO>>> indexMap = (Map<String, Map<String, List<PlanIndexVO>>>) typeMap.get(projectVOMap.get(planIndexVO.getPkProject()).getPkProjectType());
                    indexMap = getIndexMap(indexMap, planIndexVO);
                    typeMap.put(projectVOMap.get(planIndexVO.getPkProject()).getPkProjectType(),indexMap);
                    orgMap.put(projectOrgMap.get(planIndexVO.getPkProject()),typeMap);
                }
                //封装返回
                     organizationShowVO.setSname(organizationVO.getSname());
                    Map<String, Map<String, Map<String, List<PlanIndexVO>>>> typeMap = orgMap.get(organizationVO.getPkSrc());
                    List<ProjectTypeShowVO> projectTypeShowVOS = new ArrayList<>();
                    for (Map.Entry<String, Map<String, Map<String, List<PlanIndexVO>>>> typeEntry:typeMap.entrySet()){
                        ProjectTypeVO projectTypeVO = projectTypeMap.get(typeEntry.getKey());
                        ProjectTypeShowVO projectTypeShowVO = new ProjectTypeShowVO();
                        if (projectTypeVO!=null){
                            projectTypeShowVO.setSname(projectTypeVO.getSname());
                        }
                        Map<String, Map<String, List<PlanIndexVO>>> value = typeEntry.getValue();
                        List<IndexExcelShowVO> indexValue = getIndexValue(value, measureIndexVOMap, projectVOMap);
                        projectTypeShowVO.setIndexExcelShowVOS(indexValue);
                        projectTypeShowVOS.add(projectTypeShowVO);
                    }
                    organizationShowVO.setProjectTypeShowVOS(projectTypeShowVOS);
            return organizationShowVO;
        }
        return null;
    }
    //map<指标主键，map<项目主键，计划指标集合>>
    private Map<String, Map<String, List<PlanIndexVO>>> getIndexMap(Map<String, Map<String, List<PlanIndexVO>>> indexMap, PlanIndexVO planIndexVO) {
        if (indexMap == null) {
            indexMap = new LinkedHashMap<>();
        }
        Map<String, List<PlanIndexVO>> projectIndexMap = indexMap.get(planIndexVO.getPkMeasureIndex());
        if (projectIndexMap == null) {
            projectIndexMap = new LinkedHashMap<>();
        }
        List<PlanIndexVO> planIndexVOList = projectIndexMap.get(planIndexVO.getPkProject());
        if (planIndexVOList == null) {
            planIndexVOList = new ArrayList<>();
        }
        planIndexVOList.add(planIndexVO);
        projectIndexMap.put(planIndexVO.getPkProject(), planIndexVOList);
        indexMap.put(planIndexVO.getPkMeasureIndex(), projectIndexMap);
        return indexMap;
    }

    //得到指标集合List
    private List<IndexExcelShowVO> getIndexValue(Map<String, Map<String, List<PlanIndexVO>>> indexMap,Map<String, MeasureIndexVO> measureIndexVOMap,Map<String, ProjectVO> projectVOMap){
        List<IndexExcelShowVO> indexVOS = new ArrayList<>();
        for (Map.Entry<String, Map<String, List<PlanIndexVO>>> indexEntry : indexMap.entrySet()) {
            MeasureIndexVO measureIndexVO = measureIndexVOMap.get(indexEntry.getKey());
            IndexExcelShowVO indexExcelShowVO = new IndexExcelShowVO();
            indexExcelShowVO.setUnit(measureIndexVO.getUnit());
            indexExcelShowVO.setName(measureIndexVO.getName());
            indexExcelShowVO.setCode(measureIndexVO.getCode());
            Map<String, List<PlanIndexVO>> value = indexEntry.getValue();
            int indexSumNum = 0;
            List<ProjectShowVO> projectShowVOS = new ArrayList<>();
            for (Map.Entry<String, List<PlanIndexVO>> projectIdMap : value.entrySet()) {
                ProjectVO projectVO = projectVOMap.get(projectIdMap.getKey());
                ProjectShowVO projectShowVO = new ProjectShowVO();
                projectShowVO.setScode(projectVO.getScode());
                projectShowVO.setSname(projectVO.getSname());
                List<PlanIndexVO> planIndexVOList = projectIdMap.getValue();
                int projectSumNum = 0;
                for (PlanIndexVO planIndexVO : planIndexVOList) {
                    if (planIndexVO.getCompletionsNum()==null){
                        planIndexVO.setCompletionsNum(Double.valueOf(0));
                    }
                    projectSumNum += planIndexVO.getCompletionsNum();
                }
                projectShowVO.setProjectIndexNum(projectSumNum);
                indexSumNum += projectSumNum;
                projectShowVOS.add(projectShowVO);
            }
            indexExcelShowVO.setIndexSumNum(indexSumNum);
            indexExcelShowVO.setProjectShowVOS(projectShowVOS);
            indexVOS.add(indexExcelShowVO);
        }
        return indexVOS;
    }

}

